home *** CD-ROM | disk | FTP | other *** search
- /*
-
- Packed Decimal, Binary Conversion
- Copyright (c) 1994, Iambic Software, Inc.
- All rights reserved
-
- */
-
-
- #include <mem.h>
- #include "pd.h"
-
-
- short int sPackedToBin( unsigned char *pPack, long *lBin, short nLen )
- {
- /************************************************************
-
- Name: sPackedToBin
-
- Function:
-
- This routine will convert IBM 370 packed dicimal numbers to fixed
- point binary numbers four bytes long.
-
- arguments:
-
- 1. unsigned char pointer to the packed decimal number, max length
- is six bytes.
-
- 2. pointer to a long int to receive the result.
-
- 3. short int length of argument 1, the packed decimal number.
-
- return codes:
-
- 0 success
- 1 invalid decimal digit
- 2 overflow, numbers greater than 2,147,483,647 (0x7fffff)
- 3 invalid length specified
-
-
- *************************************************************/
-
-
- short int iI; /* loop index */
- unsigned short int iFirstNib; /* first nibble */
- unsigned short int iLastNib; /* last nibble */
- long int lTBin; /* binary work */
- unsigned char *pWork; /* work pointer for packed number */
-
- if ( nLen > 6 || nLen < 1 ) /* validate length */
- return( 3 );
- lTBin = 0; /* initialize work number */
- pWork = pPack; /* copy pointer to work */
- for( iI = 1; iI <= nLen; iI++ )
- {
- iFirstNib = ( *pWork & 0xf0 ) >> 4; /* obtain high order 4 bits */
- iLastNib = *pWork & 0x0f; /* obtain low order 4 bits */
- if ( iFirstNib > 0x90 ) /* check first nibble */
- return( 1 );
- if ( iI != nLen ) /* is this the last byte ? */
- {
- if ( iLastNib > 9 ) /* last nibble digit ok ? */
- return( 1 );
- }
- else
- {
- if ( iLastNib < 10 ) /* last nibble of number, for sign */
- return( 1 );
- }
- lTBin *= 10; /* shift one digit to left */
- lTBin += iFirstNib; /* add in the next number */
- if ( lTBin < 0 ) /* number has overflowed */
- return(2);
- if ( iI != nLen ) /* last byte, dont add sign */
- {
- lTBin *= 10; /* shift one byte to the left */
- lTBin += iLastNib; /* add in the next number */
- if ( lTBin < 0 ) /* number has overflowed */
- return(2);
- }
- pWork++; /* point to the next output byte */
- }
- switch ( iLastNib ) /* make negative if needed */
- {
- case 0x0b: /* negative decimal signs ? */
- case 0x0d:
- lTBin *= -1; /* make the number negative */
- break;
- }
- *lBin = lTBin; /* return the result to the source field */
- return( 0 );
- }
- /************************************************************
-
- Name: sBinToPacked
-
- Function:
-
- This routine will convert long binary number to IBM 370 packed
- decimal format eight bytes long.
-
- arguments:
-
- 1. unsigned char pointer to the packed decimal number result
- 8 bytes long
-
- 2. pointer to a long int to convert.
-
- return codes:
-
- 0 success
-
- *************************************************************/
- short int sBinToPacked( unsigned char *pPack, long *lBin )
- {
- unsigned char *pPkd; /* working pointer for packed numb */
- long lWBin; /* working binary number */
- unsigned char Pkd[8]; /* work packed number */
- short iRem; /* remainder (may cause warnings
- abount significant digits during
- compile ) */
- short iI; /* loop counter */
- lWBin = *lBin; /* copy input */
- memset( Pkd, 0, 8); /* clear number */
- pPkd = Pkd + 7; /* point to last byte of packed num */
- if ( lWBin < 0 ) /* is number negative */
- {
- *pPkd |= 0x0d; /* move in negative sign */
- lWBin *= -1; /* make it positive */
- }
- else
- *pPkd |= 0x0c; /* move in positive sign */
- iRem = lWBin % 10; /* get ones digit */
- *pPkd |= iRem << 4; /* add digit to number */
- lWBin /= 10; /* divide by 10 */
- for ( iI=1 ; iI < 8 ; iI++ ) /* setup loop for remainder of digits */
- {
- pPkd--; /* move pointer one left */
- if ( ! lWBin ) /* no more digits, exit */
- break;
- iRem = lWBin % 10; /* get next digit */
- *pPkd |= iRem; /* add digit to packed number */
- lWBin /= 10; /* divide number by 10 */
- if ( ! lWBin ) /* no more digits, exit */
- break;
- iRem = lWBin % 10; /* get next digit */
- *pPkd |= iRem << 4; /* add digit to paced number */
- lWBin /= 10; /* divide number by 10 */
- }
- memmove( pPack, Pkd, 8); /* return number to target field */
- return( 0 );
- }
-
-